package com.filldream.fastboot.web.controller.common;

import cn.hutool.http.ContentType;
import com.filldream.fastboot.common.constant.FinalStr;
import com.filldream.fastboot.common.exception.GlobalException;
import com.filldream.fastboot.common.entity.ErrorCode;
import com.filldream.fastboot.common.util.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

@Slf4j
@Api(tags = "统一地址回调")
@RestController
@AllArgsConstructor
@RequestMapping(value = "/common/callBack")
public class CallBackController {

    private WxPayV3Util wxPayV3Util;

    //此处代码为了方便放置于Controller层，请根据规范移动至相关项目层级

    @ApiOperation(value = "微信支付回调",notes = "微信支付回调")
    @PostMapping("/wx/notify")
    public String wxNotify(HttpServletRequest request) {
        System.out.println("-----------支付开始回调-------------");
        try {
            String weixinReqXml = PayUtil.getRequestData(request);
            if (!StringUtils.isEmpty(weixinReqXml)) {
                Map<String,String> wxMap = XmlUtil.xmlToMap(weixinReqXml);
                String return_code = wxMap.get("return_code");
                if ("SUCCESS".equals(return_code)) {
                    String result_code = wxMap.get("result_code");
                    String retruenSign = wxMap.get("sign");
                    wxMap.remove("sign");
                    String out_trade_no = wxMap.get("out_trade_no");// 商户系统的订单号，与请求一致
                    float total_fee = Float.parseFloat(wxMap.get("total_fee")) / 100;// 订单总金额，单位为分
                    if ("SUCCESS".equals(result_code)) {
                        String build = PayUtil.build(wxMap, "key", "yourSignKey");
                        String sign = PayUtil.sign(build);
                        // 签名校验
                        if ( sign.equals(retruenSign) ) {
                            //业务处理,可以考虑使用Mq或者事件
                            return FinalStr.WX_PAY_OK;
                        } else {
                            return FinalStr.WX_PAY_SIGN_FAIL;
                        }
                    } else {
                        // 支付失败
                        String err_code = wxMap.get("err_code");
                        String err_code_des = wxMap.get("err_code_des");
                        if ("ORDERCLOSED".equals(err_code)) {
                            DDErrorUtil.directSend( FinalStr.getProject_name()+":交易关闭:" +  err_code_des);
                            return FinalStr.WX_PAY_DATE_NULL;
                        } else {
                            DDErrorUtil.directSend( FinalStr.getProject_name()+":支付异常:" +  err_code_des);
                            return FinalStr.WX_PAY_DATE_NULL;
                        }
                    }
                } else {
                    String return_msg = wxMap.get("return_msg");
                    throw new GlobalException(ErrorCode.WECHAT_PAY_ERR.reMsg(FinalStr.getProject_name() +"回调"),return_msg,true);
                }
            }
        } catch (Exception e) {
            throw new GlobalException(ErrorCode.WECHAT_PAY_ERR.reMsg(FinalStr.getProject_name() + "回调异常"),e,true);
        }
        return FinalStr.WX_PAY_OK;
    }

    @ApiOperation(value = "微信退款回调",notes = "微信退款回调")
    @PostMapping("/wx/refundNotify")
    public String returnNotify(HttpServletRequest request) {
        log.info("-----------退款开始回调-------------");
        try {
            String weixinReqXml = PayUtil.getRequestData(request);
            log.info("--->回调数据:" + weixinReqXml);
            if (!StringUtils.isEmpty(weixinReqXml)) {
                Map<String,String> wxMap = XmlUtil.xmlToMap(weixinReqXml);
                String return_code = wxMap.get("return_code");
                if ("SUCCESS".equals(return_code)) {
                    //加密信息
                    String req_info = wxMap.get("req_info");
                    //解密信息，具体参考微信支付退款通知
                    String resultStr = EncryptUtil.decryptData(req_info,"yourSignKey","AES/ECB/PKCS5Padding","AES");
                    log.info("--->回调解密数据:" + resultStr);
                    //信息Map
                    Map<String, String> aesMap = XmlUtil.xmlToMap(resultStr);
                    //退款号
                    String out_refund_no = aesMap.get("out_refund_no");
                    //订单号
                    String out_trade_no = aesMap.get("out_trade_no");
                    //退款状态 SUCCESS-退款成功 CHANGE-退款异常 REFUNDCLOSE—退款关闭
                    String refund_status = aesMap.get("refund_status");
                    //申请退款金额
                    String refund_fee = aesMap.get("refund_fee");
                    //退款金额
                    String settlement_refund_fee = aesMap.get("settlement_refund_fee");

                    if( "SUCCESS".equals(refund_status) ){
                        //业务处理 TODO
                        return FinalStr.WX_PAY_OK;
                    }
                    return FinalStr.WX_PAY_FAIL;
                }
                return FinalStr.WX_PAY_FAIL;
            }
        } catch (Exception e) {
            return FinalStr.WX_PAY_FAIL;
        }
        return FinalStr.WX_PAY_FAIL;
    }


    @ApiOperation(value = "微信支付回调V3",notes = "微信支付V3-支付结果回调")
    @PostMapping("/wx/payNotify/v3")
    public void wxPayNotifyV3(HttpServletRequest request, HttpServletResponse response) {
        try {
            //初始化请求和返回
            request.setCharacterEncoding("UTF-8");
            response.setContentType(ContentType.JSON.getValue());
            response.setCharacterEncoding("UTF-8");
            response.setStatus(HttpServletResponse.SC_OK);

            Transaction transaction = wxPayV3Util.payNotify(request);
            //----开始处理业务----
            //请在此处填写业务代码或调用方法
            //----结束处理业务----
            try(PrintWriter writer = response.getWriter()){
                writer.write( FinalStr.WX_PAY_V3_NOTIFY_OK );
                writer.flush();
            }
        }catch (Exception e){
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try(  PrintWriter writer = response.getWriter()) {
                writer.write( FinalStr.WX_PAY_V3_NOTIFY_FAIL );
                writer.flush();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    @ApiOperation(value = "微信退款回调V3",notes = "微信支付V3-支付结果回调")
    @PostMapping("/wx/refundNotify/v3")
    public void wxRefundNotifyV3(HttpServletRequest request, HttpServletResponse response) {
        try {
            //初始化请求和返回
            request.setCharacterEncoding("UTF-8");
            response.setContentType(ContentType.JSON.getValue());
            response.setCharacterEncoding("UTF-8");
            response.setStatus(HttpServletResponse.SC_OK);

            RefundNotification refundNotification = wxPayV3Util.refundNotify(request);
            //----开始处理业务----
            //请在此处填写业务代码或调用方法
            //----结束处理业务----
            try(PrintWriter writer = response.getWriter()){
                writer.write( FinalStr.WX_PAY_V3_NOTIFY_OK );
                writer.flush();
            }
        }catch (Exception e){
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try(  PrintWriter writer = response.getWriter()) {
                writer.write( FinalStr.WX_PAY_V3_NOTIFY_FAIL );
                writer.flush();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }


}
